#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#define BLOCK_SIGNAL 2
#define MAX_SIGNUM 31

static void show_pending(const sigset_t *pending)
{
    for (int signo = MAX_SIGNUM; signo >= 1; signo--)
    {
        // 判定当前的信号是否被设置了
        if (sigismember(pending, signo))
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
    }
    printf("\n");
}

static void myhandler(const int sig)
{
    printf("%d号信号已经被递达!!\n", sig);
}

int main()
{
    // 捕捉2号信号
    signal(BLOCK_SIGNAL, myhandler);

    // 1. 先尝试屏蔽指定的信号
    sigset_t block, oblock, pending;
    // 1.1 初始化所有信号集
    sigemptyset(&block);
    sigemptyset(&oblock);
    // 1.2 添加要屏蔽的信号
    sigaddset(&block, BLOCK_SIGNAL);
    // sigaddset(&block, 3);
    // 1.3 开始屏蔽，设置进内核（进程）
    sigprocmask(SIG_SETMASK, &block, &oblock);

    // 2. 遍历打印所有的pengding信号集
    int cnt = 10;
    while (1)
    {
        // 2.1 初始化
        sigemptyset(&pending);
        // 2.2 获取它
        sigpending(&pending);
        // 2.3 打印它
        show_pending(&pending);
        // 3.慢一点
        sleep(1);
        if (cnt-- == 0)
        {
            sigprocmask(SIG_SETMASK, &oblock, &block); // 一旦对信号进行解除屏蔽，一般OS至少立马递达一个信号!!!
            // 2号信号的默认动作是退出进程,所以后面的代码不执行了
            printf("恢复对信号的屏蔽，不屏蔽任何信号\n");
        }
    }

    return 0;
}
